import { ref, createApp, h } from 'vue'
import ToastNotification from '@/components/ToastNotification.vue'

// Toast 类型
export type ToastType = 'success' | 'error' | 'warning' | 'info'

// Toast 配置接口
export interface ToastConfig {
  type?: ToastType
  title?: string
  message: string
  duration?: number
  persistent?: boolean
  retryable?: boolean
  showActions?: boolean
  onRetry?: () => Promise<void> | void
  onDismiss?: () => void
}

// Toast 实例接口
export interface ToastInstance {
  id: string
  config: ToastConfig
  show: () => void
  hide: () => void
  destroy: () => void
}

// Toast 管理器类
class ToastManager {
  private toasts = ref<ToastInstance[]>([])
  private container: HTMLElement | null = null
  private idCounter = 0

  constructor() {
    this.createContainer()
  }

  /**
   * 创建容器
   */
  private createContainer(): void {
    if (typeof window === 'undefined') return

    this.container = document.createElement('div')
    this.container.id = 'toast-container'
    this.container.style.cssText = `
      position: fixed;
      top: 0;
      right: 0;
      z-index: 9999;
      pointer-events: none;
    `
    document.body.appendChild(this.container)
  }

  /**
   * 显示 Toast
   */
  show(config: ToastConfig): ToastInstance {
    const id = `toast_${++this.idCounter}_${Date.now()}`
    
    // 创建 Toast 实例
    const toastInstance = this.createToastInstance(id, config)
    
    // 添加到列表
    this.toasts.value.push(toastInstance)
    
    // 限制同时显示的 Toast 数量
    this.limitToasts()
    
    return toastInstance
  }

  /**
   * 创建 Toast 实例
   */
  private createToastInstance(id: string, config: ToastConfig): ToastInstance {
    if (!this.container) {
      throw new Error('Toast container not initialized')
    }

    // 创建挂载点
    const mountPoint = document.createElement('div')
    mountPoint.style.pointerEvents = 'auto'
    this.container.appendChild(mountPoint)

    // 创建 Vue 应用实例
    const app = createApp({
      render: () => h(ToastNotification, {
        ...config,
        onClose: () => {
          toastInstance.destroy()
        },
        onRetry: async () => {
          if (config.onRetry) {
            try {
              await config.onRetry()
            } catch (error) {
              console.error('Toast retry failed:', error)
            }
          }
        },
        onDismiss: () => {
          config.onDismiss?.()
          toastInstance.destroy()
        }
      })
    })

    // 挂载应用
    const vm = app.mount(mountPoint)

    const toastInstance: ToastInstance = {
      id,
      config,
      show: () => {
        if (vm && typeof vm.show === 'function') {
          vm.show()
        }
      },
      hide: () => {
        if (vm && typeof vm.hide === 'function') {
          vm.hide()
        }
      },
      destroy: () => {
        // 从列表中移除
        const index = this.toasts.value.findIndex(toast => toast.id === id)
        if (index > -1) {
          this.toasts.value.splice(index, 1)
        }

        // 销毁 Vue 应用
        try {
          app.unmount()
        } catch (error) {
          console.warn('Error unmounting toast app:', error)
        }

        // 移除 DOM 元素
        if (mountPoint.parentNode) {
          mountPoint.parentNode.removeChild(mountPoint)
        }
      }
    }

    return toastInstance
  }

  /**
   * 限制 Toast 数量
   */
  private limitToasts(maxToasts: number = 5): void {
    while (this.toasts.value.length > maxToasts) {
      const oldestToast = this.toasts.value[0]
      oldestToast.destroy()
    }
  }

  /**
   * 显示成功消息
   */
  success(message: string, config?: Partial<ToastConfig>): ToastInstance {
    return this.show({
      type: 'success',
      message,
      duration: 3000,
      ...config
    })
  }

  /**
   * 显示错误消息
   */
  error(message: string, config?: Partial<ToastConfig>): ToastInstance {
    return this.show({
      type: 'error',
      message,
      duration: 5000,
      retryable: true,
      ...config
    })
  }

  /**
   * 显示警告消息
   */
  warning(message: string, config?: Partial<ToastConfig>): ToastInstance {
    return this.show({
      type: 'warning',
      message,
      duration: 4000,
      ...config
    })
  }

  /**
   * 显示信息消息
   */
  info(message: string, config?: Partial<ToastConfig>): ToastInstance {
    return this.show({
      type: 'info',
      message,
      duration: 3000,
      ...config
    })
  }

  /**
   * 显示加载消息
   */
  loading(message: string, config?: Partial<ToastConfig>): ToastInstance {
    return this.show({
      type: 'info',
      message,
      persistent: true,
      showActions: false,
      ...config
    })
  }

  /**
   * 清除所有 Toast
   */
  clear(): void {
    const toasts = [...this.toasts.value]
    toasts.forEach(toast => toast.destroy())
  }

  /**
   * 清除指定类型的 Toast
   */
  clearByType(type: ToastType): void {
    const toasts = this.toasts.value.filter(toast => toast.config.type === type)
    toasts.forEach(toast => toast.destroy())
  }

  /**
   * 获取当前 Toast 列表
   */
  getToasts(): ToastInstance[] {
    return [...this.toasts.value]
  }

  /**
   * 获取指定类型的 Toast 数量
   */
  getCountByType(type: ToastType): number {
    return this.toasts.value.filter(toast => toast.config.type === type).length
  }

  /**
   * 销毁管理器
   */
  destroy(): void {
    this.clear()
    
    if (this.container && this.container.parentNode) {
      this.container.parentNode.removeChild(this.container)
      this.container = null
    }
  }
}

// 创建全局 Toast 管理器实例
export const toastManager = new ToastManager()

// 便捷函数
export const showToast = (config: ToastConfig): ToastInstance => {
  return toastManager.show(config)
}

export const showSuccess = (message: string, config?: Partial<ToastConfig>): ToastInstance => {
  return toastManager.success(message, config)
}

export const showError = (message: string, config?: Partial<ToastConfig>): ToastInstance => {
  return toastManager.error(message, config)
}

export const showWarning = (message: string, config?: Partial<ToastConfig>): ToastInstance => {
  return toastManager.warning(message, config)
}

export const showInfo = (message: string, config?: Partial<ToastConfig>): ToastInstance => {
  return toastManager.info(message, config)
}

export const showLoading = (message: string, config?: Partial<ToastConfig>): ToastInstance => {
  return toastManager.loading(message, config)
}

export const clearToasts = (): void => {
  toastManager.clear()
}

export const clearToastsByType = (type: ToastType): void => {
  toastManager.clearByType(type)
}

// Vue 插件
export const toastPlugin = {
  install(app: any) {
    app.config.globalProperties.$toast = toastManager
    app.config.globalProperties.$showToast = showToast
    app.config.globalProperties.$showSuccess = showSuccess
    app.config.globalProperties.$showError = showError
    app.config.globalProperties.$showWarning = showWarning
    app.config.globalProperties.$showInfo = showInfo
    app.config.globalProperties.$showLoading = showLoading
    
    app.provide('toast', toastManager)
  }
}

// 组合式 API
export const useToast = () => {
  return {
    show: showToast,
    success: showSuccess,
    error: showError,
    warning: showWarning,
    info: showInfo,
    loading: showLoading,
    clear: clearToasts,
    clearByType: clearToastsByType,
    manager: toastManager
  }
}

// 错误处理集成
export const showErrorToast = (error: any, config?: Partial<ToastConfig>) => {
  let message = '发生未知错误'
  let retryable = false

  if (typeof error === 'string') {
    message = error
  } else if (error?.message) {
    message = error.message
    
    // 根据错误类型判断是否可重试
    if (error.code >= 500 || error.name?.includes('Network') || error.name?.includes('Timeout')) {
      retryable = true
    }
  }

  return showError(message, {
    retryable,
    ...config
  })
}

// 成功操作反馈
export const showSuccessToast = (message: string, config?: Partial<ToastConfig>) => {
  return showSuccess(message, {
    duration: 2000,
    ...config
  })
}

// 网络状态提示
export const showNetworkToast = (isOnline: boolean) => {
  if (isOnline) {
    return showSuccess('网络连接已恢复', {
      duration: 2000
    })
  } else {
    return showWarning('网络连接已断开', {
      persistent: true
    })
  }
}

// 监听网络状态变化
if (typeof window !== 'undefined') {
  window.addEventListener('online', () => showNetworkToast(true))
  window.addEventListener('offline', () => showNetworkToast(false))
}